#include "UtilCommon.h"

bool ConfigFile::Load()
{
	readlock.Acquire();
	std::ifstream istr(m_filename, std::ios::in);
	if(!istr)
	{
		Log->Notice("ConfigHandler", "Could not open configfile '%s'!", m_filename);
		readlock.Release();
		return false;
	}
	const char* cblockname = NULL;
	Block* curblock = new Block();
	while(!istr.eof())
	{
		char* buffer = new char[255];
		istr.getline(buffer, 255);
		if(!strlen(buffer))
			continue;
		if(buffer[0] == '[')
		{
			if(cblockname)
			{
				blocks.insert(std::make_pair<const char*, Block*>(cblockname, curblock));
				cblockname = NULL;
				curblock = new Block();
			}
			cblockname = strtok(buffer + 1, "]");
			if(!cblockname)
			{
				Log->Notice("ConfigHandler", "Got unexpected block end!");
				readlock.Release();
				return false;
			}
			continue;
		}
		if(buffer[0] == '#')
			continue;
		char* describer = strtok(buffer, "=");
		char* value = strtok(NULL, "\n");
		if(!value)
		{
			Log->Warning("ConfigHandler", "Got no value for describer '%s'! Setting default value (\"\")", describer);
			value = "";
		}
		curblock->values.insert(std::make_pair<const char*, const char*>(describer, value));
	}

	if(cblockname)
	{
		blocks.insert(std::make_pair<const char*, Block*>(cblockname, curblock));
	}

	readlock.Release();
	return true;
}

char* ConfigFile::GetChar(const char* blockname, const char* describer)
{
	readlock.Acquire();
	std::map<const char*, Block*>::iterator itr = blocks.begin();
	std::map<const char*, Block*>::iterator end = blocks.end();

	Block* block = NULL;

	for( ; itr != end; ++itr)
	{
		if(!strcmp(itr->first, blockname))
		{
			block = itr->second;
			break;
		}
	}

	if(!block)
	{
		readlock.Release();
		return NULL;
	}

	std::map<const char*, const char*>::iterator initr = block->values.begin();
	std::map<const char*, const char*>::iterator inend = block->values.end();

	for( ; initr != inend; ++initr)
	{
		if(!strcmp(initr->first, describer))
		{
			readlock.Release();
			return (char*)initr->second;
		}
	}

	readlock.Release();
	return NULL;
}

float ConfigFile::GetFloat(const char* block, const char* describer, float defaul)
{
	char* tmp = GetChar(block, describer);
	if(!tmp)
		return defaul;
	else
		return (float)atof(tmp);
}

i32 ConfigFile::GetInt(const char* block, const char* desc, i32 def)
{
	char* tmp = GetChar(block, desc);
	if(!tmp)
		return def;
	else
		return atoi(tmp);
}

bool ConfigFile::GetBool(const char* b, const char* d, bool def)
{
	char* tmp = GetChar(b, d);
	if(!tmp)
		return def;
	else
		return (atoi(tmp) != 0);
}

ui32 ConfigFile::GetUInt(const char* b, const char* d, ui32 def)
{
	char* tmp = GetChar(b, d);
	if(!tmp)
		return def;
	else
		return atoi(tmp);
}